package semant.first_pass;

import semant.Env;
import symbol.ClassInfo;
import symbol.MethodInfo;
import symbol.Symbol;
import syntaxtree.MethodDecl;
import syntaxtree.Type;
import syntaxtree.VisitorAdapter;

/**
 * 
 * @author gabriel
 * 
 */
public class MethodDeclHandler extends VisitorAdapter {

	private Env env;
	private ClassInfo info;

	public MethodDeclHandler(Env e, ClassInfo i) {
		super();
		env = e;
		info = i;
	}

	public static void firstPass(Env e, ClassInfo i, MethodDecl node) {
		MethodDeclHandler h = new MethodDeclHandler(e, i);
		node.accept(h);
	}

	@Override
	public void visit(MethodDecl node) {
		Type t = node.returnType;
		Symbol name = Symbol.symbol(node.name.s);
		MethodInfo m = new MethodInfo(t, name, info.name);

		// processando os parametros do metodo
		FormalDeclListHandler.firstPass(env, info, m, node.formals);

		// processando as variaveis locais do metodo
		LocalDeclListHandler.firstPass(env, info, m, node.locals);

		// adicionando o metodo da classe
		if (!info.addMethod(m)) {
			MethodInfo old = info.methods.get(name);

			env.err.Error(node.name, new Object[] {
					"Redeclaracao do metodo \'" + name + "\' "
							+ "na classe: \'" + info.name + "\'. ",
					"Declaracao anterior em: [" + old.type.line + ", "
							+ old.type.row + "]" });
		}
	}

}
